package web.pda.sgcc.com.websdk.http.file.download;

import android.support.annotation.NonNull;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义下载的线程池.
 *
 * @author 王沛栋
 * @data 2018/2/23 11:03
 */

public class ThreadPool {

    //定义同时现在的任务数(核心线程数)
    private int CORE_POOL_SIZE = 3;
    //缓存队列的大小(最大线程数)
    private int MAX_POOL_SIZE = 20;
    //非核心线程闲置的常熟时间(秒)，超时被回收
    private long KEEP_ALIVE = 10L;

    private ThreadPoolExecutor THREAD_POOL_EXECUTOR;

    private ThreadFactory mTreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger();

        @Override
        public Thread newThread(@NonNull Runnable r) {
            return new Thread(r, "download_task:" + mCount);
        }
    };

    private ThreadPool() {
    }

    public static ThreadPool getInstance() {
        return SingletonHolder.instance;
    }

    private static class SingletonHolder {
        private static final ThreadPool instance = new ThreadPool();

        private SingletonHolder() {
        }
    }

    /**
     * 设置核心线程数
     *
     * @param corePoolSize
     */
    public void setCorePoolSize(int corePoolSize) {
        if (corePoolSize <= 0) {
            return;
        }
        CORE_POOL_SIZE = corePoolSize;
    }

    /**
     * 设置最大线程数
     *
     * @param maxPoolSize
     */
    public void setMaxPoolSize(int maxPoolSize) {
        if (maxPoolSize <= 0) {
            return;
        }
        MAX_POOL_SIZE = maxPoolSize;
    }

    /**
     * 获取核心线程数
     *
     * @return
     */
    public int getCorePoolSize() {
        return CORE_POOL_SIZE;
    }

    /**
     * 获取最大线程数
     *
     * @return
     */
    public int getMaxPoolSize() {
        return MAX_POOL_SIZE;
    }

    /**
     * 获取线程执行数
     *
     * @return
     */
    public ThreadPoolExecutor getThreadPoolExecutor() {
        if (THREAD_POOL_EXECUTOR == null) {
            THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
                    CORE_POOL_SIZE, MAX_POOL_SIZE,
                    KEEP_ALIVE, TimeUnit.SECONDS,
                    new LinkedBlockingDeque<Runnable>(),
                    mTreadFactory
            );
        }
        return THREAD_POOL_EXECUTOR;
    }
}
